﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Threading.Tasks;
using TransformerManager.API.Utils;
using TransformerManager.EF.Models;
using TransformerManager.Shared.Dto;
using TransformerManager.Shared.Helper;
using TransformerManager.Shared.Helper.HttpParams;
using TransformerManager.Shared.Servers;

namespace TransformerManager.API.Controllers
{
    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    [ApiController]
    [Authorize]
    public class AccountController : Controller
    {
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly IUserService _userService;
        private readonly IUrlHelper _urlHelper;

        public AccountController(
            UserManager<ApplicationUser> userManager,
            IActionContextAccessor actionContextAccessor,
            IUrlHelperFactory urlHelperFactory,
            IUserService userService
            )
        {
            _userManager = userManager;
            _userService = userService;
            _urlHelper = urlHelperFactory.GetUrlHelper(actionContextAccessor.ActionContext);

        }

        /// <summary>
        /// 根据用户名获取用户信息
        /// </summary>
        /// <param name="userName">用户名，用户账户</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpGet("userName/{userName}")]
        public async Task<IActionResult> GetUserInfoByName([FromRoute] string userName)
        {
            if (string.IsNullOrEmpty(userName))
            {
                return BadRequest(new ApiResponseParams("用户名为空,无法检索数据!", null));
            }

            var user = await _userManager.FindByNameAsync(userName);
            if (user == null)
            {
                return NotFound(new ApiResponseParams($"检索不到用户 {userName}", null));
            }

            var roles = await _userManager.GetRolesAsync(user);

            return Ok(new ApiResponseParams(
                string.Empty,
                new UserBasicParams
                {
                    UserId = user.Id,
                    RealNameEn = user.RealNameEn,
                    RealNameCn = user.RealNameCn,
                    Department = user.Department,
                    IsLeadEngineer = user.IsLeadEngineer,
                    Roles = roles
                }));
        }

        /// <summary>
        /// 根据用户GUID获取用户信息
        /// </summary>
        /// <param name="userId">用户GUID</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpGet("userId/{userId}")]
        public async Task<IActionResult> GetUserInfoById([FromRoute] string userId)
        {
            var user = await _userService.GetUserByIdAsync(userId);
            if (user == null)
            {
                return NotFound(new ApiResponseParams($"Id: {userId}不存在", null));
            }

            var roles = await _userManager.GetRolesAsync(user);

            return Ok(new ApiResponseParams(
                        string.Empty,
                        new UserBasicParams()
                        {
                            UserId = user.Id,
                            RealNameEn = user.RealNameEn,
                            RealNameCn = user.RealNameCn,
                            Department = user.Department,
                            IsLeadEngineer = user.IsLeadEngineer,
                            Roles = roles
                        }));
        }            

        /// <summary>
        /// 通过关键字获取用户列表
        /// </summary>
        /// <param name="keywords">关键字(用户名，用户中文名或用户英文名)</param>
        /// <param name="onlyLeadEngineer">是否只包含主设</param>
        /// <param name="paginationParams">分页参数</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpGet("users", Name = "GetAllUsersInfo")]
        [HttpHead("users")]
        public async Task<IActionResult> GetAllUsersInfo(
            [FromQuery] string keywords,
            [FromQuery] bool onlyLeadEngineer,
            [FromQuery] PaginationResourceParameters paginationParams)
        {
            var usersFromRepo = await _userService.GetUsersInfoAsync(keywords, onlyLeadEngineer, paginationParams);

            if(usersFromRepo == null || usersFromRepo.Count == 0)
            {
                return NotFound(new ApiResponseParams("没有检索到用户", null));
            }

            // 生成前一页的URL
            var previousPageLink = usersFromRepo.HasPrevious ?
                HttpUtils.GenerateRouteResourceURL(
                    paginationParams,
                    "GetAllUsersInfo",
                    ResourceUrlType.PreviousPage,
                    _urlHelper) : null;

            // 生成后一页的URL
            var nextPageLink = usersFromRepo.HasNext ?
                HttpUtils.GenerateRouteResourceURL(
                    paginationParams,
                    "GetAllUsersInfo",
                    ResourceUrlType.NextPage,
                    _urlHelper) : null;

            var paginationMetadata = new
            {
                previousPageLink,
                nextPageLink,
                totalCount = usersFromRepo.TotalCount,
                pageSize = usersFromRepo.PageSize,
                currentPage = usersFromRepo.CurrentPage,
                totalPages = usersFromRepo.TotalPages
            };

            // 通过Response的头部信息返回hatos成熟度3等级的restful头信息
            Response.Headers.Add("x-pagination",
                Newtonsoft.Json.JsonConvert.SerializeObject(paginationMetadata));

            List<UserBasicParams> userBasicInfos = new List<UserBasicParams>();
            foreach (var user in usersFromRepo)
            {
                var roles = await _userManager.GetRolesAsync(user);
                var userBasicInfo = new UserBasicParams()
                {
                    UserId = user.Id,
                    UserName = user.UserName,
                    RealNameEn = user.RealNameEn,
                    RealNameCn = user.RealNameCn,
                    Department = user.Department,
                    IsLeadEngineer = user.IsLeadEngineer,
                    Roles = roles
                };
                userBasicInfos.Add(userBasicInfo);
            }

            return Ok(new ApiResponseParams(string.Empty, userBasicInfos));
        }

        /// <summary>
        /// 授权用户为管理员
        /// </summary>
        /// <param name="authorizeUserDto">授权用户管理员权限参数</param>
        /// <returns></returns>
        [Authorize(Roles = "SuperAdmin")]
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPost("authorize")]
        public async Task<IActionResult> AuthorizeUser([FromBody] AuthorizeUserParams authorizeUserDto)
        {
            if (string.IsNullOrEmpty(authorizeUserDto.UserName))
            {
                return BadRequest(new ApiResponseParams("用户名为空,无法检索数据!", null));
            }

            var user = await _userManager.FindByNameAsync(authorizeUserDto.UserName);
            if (user == null)
            {
                return NotFound(new ApiResponseParams($"检索不到用户 {authorizeUserDto.UserName}", null));
            }

            var userRoles = await _userManager.GetRolesAsync(user);
            if (userRoles.Contains(authorizeUserDto.RoleName))
            {
                return Conflict(new ApiResponseParams($"用户{user.RealNameCn}已经是Admin", null));
            }

            await _userManager.AddToRoleAsync(user, authorizeUserDto.RoleName);

            return Ok(new ApiResponseParams($"已授权{user.RealNameCn}为{authorizeUserDto.RoleName}", null));
        }

        /// <summary>
        /// 取消用户的管理员权限
        /// </summary>
        /// <param name="unauthorizeUserDto">取消授权参数</param>
        /// <returns></returns>
        [Authorize(Roles = "SuperAdmin")]
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPost("unauthorize")]
        public async Task<IActionResult> UnauthorizeUser([FromBody] UnauthorizeUserDto unauthorizeUserDto)
        {
            if (string.IsNullOrEmpty(unauthorizeUserDto.UserName))
            {
                return BadRequest(new ApiResponseParams("用户名为空,无法进行取消授权!", null));
            }

            var user = await _userManager.FindByNameAsync(unauthorizeUserDto.UserName);
            if (user == null)
            {
                return NotFound(new ApiResponseParams($"检索不到用户 {unauthorizeUserDto.UserName}", null));
            }

            var userRoles = await _userManager.GetRolesAsync(user);
            if (userRoles.Contains(unauthorizeUserDto.RoleName))
            {
                await _userManager.RemoveFromRolesAsync(user, new List<string>() { unauthorizeUserDto.RoleName });

                return Ok(new ApiResponseParams($"已取消授权{user.RealNameCn}为{unauthorizeUserDto.RoleName}", null));
            }

            return BadRequest(new ApiResponseParams($"取消授权{user.RealNameCn}为{unauthorizeUserDto.RoleName}操作失败!", null));
        }

        /// <summary>
        /// 重置用户密码
        /// </summary>
        /// <param name="userName">需要被重置的用户名</param>
        /// <returns></returns>
        [Authorize(Roles = "SuperAdmin")]
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPost("pwdreset/{userName}")]
        public async Task<IActionResult> ResetPassword([FromRoute] string userName)
        {
            if (string.IsNullOrEmpty(userName))
            {
                return BadRequest(new ApiResponseParams("用户名为空,无法重置密码!", null));
            }

            var user = await _userManager.FindByNameAsync(userName);
            if (user == null)
            {
                return NotFound(new ApiResponseParams($"检索不到用户 {userName}", null));
            }

            var token = await _userManager.GeneratePasswordResetTokenAsync(user);

            await _userManager.ResetPasswordAsync(user, token, "123456");

            return Ok(new ApiResponseParams($"用户{userName}|{user.RealNameCn}的密码重置成功!", null));
        }

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="passwordModifyDto">修改密码参数</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPost("pwdchange")]
        public async Task<IActionResult> ModifyPassword([FromBody] PasswordModifyDto passwordModifyDto)
        {
            if (string.IsNullOrEmpty(passwordModifyDto.UserName))
            {
                return BadRequest(new ApiResponseParams("用户名为空,无法修改密码!", null));
            }

            var user = await _userManager.FindByNameAsync(passwordModifyDto.UserName);
            if (user == null)
            {
                return NotFound(new ApiResponseParams($"检索不到用户 {passwordModifyDto.UserName}", null));
            }

            var result = await _userManager.ChangePasswordAsync(user,
                passwordModifyDto.CurrentPassword, passwordModifyDto.NewPassword);

            if (!result.Succeeded)
            {
                return Unauthorized(new ApiResponseParams($"用户{passwordModifyDto.UserName}的密码修改失败,请检查当前用户密码是否正确!", null));
            }

            return Ok(new ApiResponseParams($"用户{passwordModifyDto.UserName}的密码修改成功!", null));
        }

        /// <summary>
        /// 更新指定用户的信息
        /// </summary>
        /// <param name="editUserInfoDto">用户信息参数</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPost("userinfo")]
        public async Task<IActionResult> UpdateUserInformation([FromBody] EditUserInfoDto editUserInfoDto)
        {
            if (string.IsNullOrEmpty(editUserInfoDto.UserName))
            {
                return BadRequest(new ApiResponseParams("用户名为空,无法更新用户信息!", null));
            }

            var user = await _userManager.FindByNameAsync(editUserInfoDto.UserName);
            if (user == null)
            {
                return NotFound(new ApiResponseParams($"检索不到用户 {editUserInfoDto.UserName}", null));
            }

            user.RealNameEn = string.IsNullOrEmpty(editUserInfoDto.RealNameEn) ?
                user.RealNameEn : editUserInfoDto.RealNameEn;

            user.RealNameCn = string.IsNullOrEmpty(editUserInfoDto.RealNameCn) ?
                user.RealNameCn : editUserInfoDto.RealNameCn;

            user.IsLeadEngineer = editUserInfoDto.IsLeadEngineer;

            user.Department = editUserInfoDto.Department == user.Department ?
                 user.Department : editUserInfoDto.Department;

            await _userManager.UpdateAsync(user);

            return Ok(new ApiResponseParams($"用户{editUserInfoDto.UserName}的个人信息已更新!", null));
        }
    }
}
